<template>
  <el-input :id="id" :name="props.name" :type="props.type" v-model="valueModel" @change="onChange"
             :placeholder="props.placeholder" clearable></el-input>
</template>

<script setup>
import {ref, watch, inject} from 'vue';

import Layers from "@/lang/layers/index";
import Asserts from "@/lang/core/asserts";

/**
 * 文本输入框
 */
const props = defineProps({
    // 字段名
    name: {type: String}
    // 类型，对应于 input 类型
    , type: {type: String, default: 'text'}
    // 默认值，注意 value 是单向输入，需要通过 change 事件侦听变化
    , value: {type: [String, Number, Boolean], default: undefined}
    // 文字提示
    , placeholder: {type: String, default: ''}
});

// Emits
const emit = defineEmits(['change']);

/**
 * 组件使用的对象模型
 *
 * @type {FastForm}
 */
const fast_form = inject('fast_form');

/**
 * 组件使用的对象模型
 *
 * @type {FormInput}
 */
const input = fast_form.getFormInput(props.name);
Asserts.notBlank(input, 'form input is undefined:' + props.name);

// 组件 ID
const id = ref(input.id);

// 定义要触发的事件，用于更新 v-model 的值
const valueModel = ref(props.value);

/**
 * 监听父组件传递的 value 变化
 *
 * 如果发生变化，通知到 FormInput，由 FormInput 进行业务流转
 */
watch(() => props.value, (val) => {
    input.setValue(val);
});

/**
 * 用户输入变换事件
 *
 * 通知到 FormInput，由 FormInput 进行业务流转
 *
 * @param val
 */
const onChange = (val) => {
    emit('change', val);
    input.changeValue(val);
}

/**
 * 数据受控函数
 *
 * 数据发生变化的时候，会通知到当前组件
 *
 * @see FormInput
 * @param val
 */
const onChangeValue = (val) => {
    valueModel.value = val;
}

// 设置初值
input.setValue(props.value);

// 注册输入组件侦听
input.setDom({onChangeValue})
</script>